__DefBitFieldType FLOSH<1>
    NoSH;
    SH;

__DefGroup XU : [ALL]
  __Encoding
    field<12,  3> Pred pg=PT;
    field<15,  1> PModi pg.not=False;

__DefOptype MUFU : [XU]
  __Encoding
    field< 0, 8> Optype optype == MUFU;

    field<16,  8> Reg rd;
    field<78,  3> MUFUOp mufuop;
    field<81,  3> MUFUDType dtype;
    // field<77,  1> FPSat sat = NoSAT;  // TODO

  __Exception
    EncodingError<IllegalBitFieldCombination, "MUFU.F64H only supports RCP/RSQ."> = (dtype=="F64H") and (mufuop!="RCP") and (mufuop!="RSQ");

  __Syntax
```asm          
MUFU.mufuop.dtype{.SAT} Rd, {-}{|}SrcB{.hsel}{|}      $sched $req $wsb ;

.mufuop = {.COS, .SIN, .EX2, .LG2, .RCP, .RSQ, .SQRT, .TANH}
.dtype = {.F32, .F64, .F16_V2, .BF16_V2, .F16, .BF16}
.hsel = {.H0, .H1}
```

  __Description
提供特殊函数的求值功能，可支持：
- 正弦函数
- 余弦函数
- 底数为2的指数函数
- 底数为2的对数函数
- 倒数函数
- 倒数平方根函数
- 算术平方根函数
- 双曲正切函数

总计8种特殊函数。

  __OperandInfo
输出操作数Rd必须是32bit位宽的GPR。若输出位宽不足32bit，Rd的高位将填0。

输入操作数SrcB必须是32bit位宽，合法来源：GPR、UR、Imm和cmem。

SrcB使用立即数输入时：
- 如果.dtype = .F16_V2，SrcB只能以F16ImmX2作为输入
- 如果.dtype = .BF16_V2，SrcB只能以BF16ImmX2作为输入
- 如果.dtype = .F16或.BF16，SrcB只能以Imm32作为输入
- 如果.dtype = .F32，SrcB只能以F32Imm作为输入

当.dtype = .F32或.F64时，SrcB可以选择添加绝对值和相反数修饰符。

当.dtype = .F16或.BF16时，SrcB必须添加.hsel修饰符:
- .hsel = .H0，表示选取SrcB的低16bit作为输入
- .hsel = .H1，表示选取SrcB的高16bit作为输入

  __ModifierInfo
.mufuop修饰符描述要进行求值的特殊函数：

| .mufuop | 特殊函数 |
|:----|:----------|
|.COS | 正弦函数 |
|.SIN | 余弦函数 |
|.EX2 | 底数为2的指数函数 |
|.LG2 | 底数为2的对数函数 |
|.RCP | 倒数函数 |
|.RSQ | 倒数平方根函数 |
|.SQRT| 算术平方根函数 |
|.TANH| 双曲正切函数   |

.dtype修饰符表示操作数类型，可取值包括：.F32、.F64、.F16_V2、.BF16_V2、.F16和.BF16。

目前MUFU指令可支持的特殊函数与操作数类型的合法组合如下：

| .mufuop | .dtype |
|:----|:------|
|.COS/.SIN| .F32 |
|.EX2 | .F32/.F16/.F16_V2/.BF16/.BF16_V2 |
|.LG2 | .F32 |
|.RCP | .F32/.F64 |
|.RSQ | .F32/.F64 |
|.SQRT| .F32 |
|.TANH| .F32/.F16/.F16_V2/.BF16/.BF16_V2 |

当.dtype = .F32时，可以选择启用.SAT修饰符（默认关闭），表示将结果饱和到[+0.0, +1.0]的范围内（结果中的NAN将被映射到+0.0）。

  __Semantics
MUFU指令的语义很清晰，需要注意的是不同特殊函数接受特定输入时的数值行为，请参考下面各小节。

以下各小节中输出（output）的QNAN，其二进制编码取决于操作数类型，与输入无关：
- .dtype = .F32，QNAN = 0x7FFFFFFFF
- .dtype = .F16/.BF16，QNAN = 0x7FFF
- .dtype = .F64，QNAN = 0x7FFFFFFF00000000
- .dtype = .F16_V2/.BF16_V2，QNAN = 0x7FFF7FFF

### COS/SIN
| input | output |
|:------|:------|
| ±Inf | QNAN |
| -0.0 | -0.0 |
| +0.0 | +0.0 |
| NAN | QNAN |

### EX2
| input | output |
|:------|:------|
| -Inf | +0.0 |
| ±0.0 | +1.0 |
| +Inf | +Inf |
| NAN | QNAN |

### LG2
| input | output |
|:------|:------|
| -Inf | QNAN |
| 负数 | QNAN |
| ±0.0 | -Inf |
| +Inf | +Inf |
| NAN | QNAN |

### RCP.F32
| input | output |
|:------|:------|
| -Inf | -0.0 |
| -0.0 | -Inf |
| +0.0 | +Inf |
| +Inf | +0.0 |
| NAN | QNAN |

### RCP.F64
| input | output |
|:------|:------|
| -Inf | -0.0 |
| -subnormal | -Inf |
| -0.0 | -Inf |
| +0.0 | +Inf |
| +subnormal | +Inf |
| +Inf | +0.0 |
| NAN | QNAN |

### RSQ.F32
| input | output |
|:------|:------|
| -Inf | QNAN |
| 负数 | QNAN |
| -0.0 | -Inf |
| +0.0 | +Inf |
| +Inf | +0.0 |
| NAN | QNAN |

### RSQ.F64
| input | output |
|:------|:------|
| -Inf | QNAN |
| -subnormal | -Inf |
| -0.0 | -Inf |
| +0.0 | +Inf |
| +subnormal | +Inf |
| +Inf | +0.0 |
| NAN | QNAN |

### SQRT
| input | output |
|:------|:------|
| -Inf | QNAN |
| 负数 | QNAN |
| -0.0 | -0.0 |
| +0.0 | +0.0 |
| +Inf | +Inf |
| NAN | QNAN |

### TANH
| input | output |
|:------|:------|
| -Inf | -1.0 |
| -0.0 | -0.0 |
| +0.0 | +0.0 |
| +Inf | +1.0 |
| NAN | QNAN |

  __Examples
```asm
MUFU.SQRT.F32 R7, R0 ; // R7 = sqrt(R0)
```

__DefOpcode MUFU_R : [MUFU]  //
  __Encoding
    field< 8, 4> SType stype == R;

    field<32, 8> Reg rb;

    field<72,  1> HSel rb.hsel;
    field<96,  1> SignModi rb.neg = False;
    field<97,  1> SignModi rb.abs = False;
  __OperandInfo
    InList<pg, rb>;
    OutList<rd>;
    Order<pg, rd, rb>;
    Bitwidth<rd> = 32;
    Bitwidth<rb> = 32;

__DefOpcode MUFU_I : [MUFU]  //
  __Encoding
    field< 8, 4> SType stype == I;
    field<32, 32> F32Imm vb;
  __OperandInfo
    InList<pg, vb>;
    OutList<rd>;
    Order<pg, rd, vb>;
    Bitwidth<rd> = 32;
    Bitwidth<vb> = 32;
    AsmFormat<vb> = CvtFImm(vb, dtype);

__DefOpcode MUFU_C : [MUFU]  //
  __Encoding
    field< 8, 4> SType stype == C;
    field<32, 22> CMem vb;   // TODO: 确认constant memory编码bit
    field<96,  1> SignModi vb.neg = False;
    field<97,  1> SignModi vb.abs = False;
    field<72,  1> HSel vb.hsel;
  __OperandInfo
    InList<pg, vb>;
    OutList<rd>;
    Order<pg, rd, vb>;
    Bitwidth<rd> = 32;
    Bitwidth<vb> = 32;

__DefOpcode MUFU_U : [MUFU]  //
  __Encoding
    field< 8,  4> SType stype == RU;
    field<32,  6> UReg urb;
    field<96,  1> SignModi urb.neg = False;
    field<97,  1> SignModi urb.abs = False;
    field<72,  1> HSel urb.hsel;
  __OperandInfo
    InList<pg, urb>;
    OutList<rd>;
    Order<pg, rd, urb>;
    Bitwidth<rd> = 32;
    Bitwidth<urb> = 32;

__DefOptype POPC : [XU]
  __Encoding
    field<0,  8>  Optype optype==POPC;
    field<16, 8> Reg rd;

  __Syntax
```asm          
POPC Rd, {~}SrcB      $sched $req ;
```

  __Description
计算输入32bit操作数SrcB的二进制表示中为1的bit数（即population count），将结果写入32bit无符号整数Rd。

  __OperandInfo
Rd必须来源于GPR。

SrcB可以来源于GPR、UR、Imm32和cmem。

SrcB可以选择添加一个按位取反前缀（~），表示对来源按位取反作为输入。

  __Semantics
```asm
POPC Rd, SrcB:
    UINT32 c = 0;
    while (SrcB != 0) {
        if (SrcB & 0x1) {
            c++;
        }
        a >>= 1;
    }
    Rd = c;
```

  __Examples
```asm
POPC R0, R1;
```

__DefOpcode POPC_R : [POPC]
  __Encoding
    field<8,  4> SType stype==R;
    field<32, 8> Reg rb;
    field<97, 1> SignModi rb.bitnot=False;
  __OperandInfo
    InList<pg, rb>;
    OutList<rd>;
    Order<pg, rd, rb>;
    Bitwidth<rd> = 32;
    Bitwidth<rb> = 32;

__DefOpcode POPC_I : [POPC]
  __Encoding
    field<8,  4> SType stype==I;
    field<32,32> SImm32 vb;
  __OperandInfo
    InList<pg, vb>;
    OutList<rd>;
    Order<pg, rd, vb>;
    Bitwidth<rd> = 32;
    Bitwidth<vb> = 32;

__DefOpcode POPC_U : [POPC]
  __Encoding
    field<8,  4> SType stype==U;
    field<32, 6> UReg urb;
    field<97, 1> SignModi urb.bitnot=False;
  __OperandInfo
    InList<pg, urb>;
    OutList<rd>;
    Order<pg, rd, urb>;
    Bitwidth<rd> = 32;
    Bitwidth<urb> = 32;

__DefOpcode POPC_C : [POPC]
  __Encoding
    field<8,  4> SType stype==C;
    field<32, 22> CMem vb;
    field<97, 1> SignModi vb.bitnot=False;
  __OperandInfo
    InList<pg, vb>;
    OutList<rd>;
    Order<pg, rd, vb>;
    Bitwidth<rd> = 32;
    Bitwidth<vb> = 32;

__DefOptype FLO : [XU]
  __Encoding
    field<0,  8>  Optype optype==FLO;

    field<16, 8> Reg rd;
    field<80, 1> IType itype=S32;
    field<81, 1> FLOSH sh=NoSH;

  __Syntax
```asm          
FLO{.SH}{.itype} Rd, {~}SrcB      $sched $req ;

.itype = {.S32*, .U32}
```

  __Description
计算32bit输入操作数SrcB绝对值的二进制表示的最高非零比特的位置。

即Rd = findMostSignificantOneBit(|SrcB|)。

对32bit中各比特的位置，规定最低位的位置是0，最高位是31，以此类推。

特别的，如果SrcB为0，则输出恒定为Rd = 0xFFFFFFFF。

  __OperandInfo
Rd必须来源于GPR。

SrcB可以来源于GPR、UR、Imm32和cmem。

SrcB可以选择添加一个按位取反前缀（~），表示对来源按位取反作为输入。

  __ModifierInfo
.itype表示输入操作数SrcB的类型，可取.S32（默认值，可省略）或.U32。

可选修饰符.SH表示用31减去计算结果输出，也就是如果要把最高非零bit左移到所需的移位数。

  __Semantics
```asm
FLO.itype.sh Rd, SrcB:
    // 对输入0需要特殊处理
    if (SrcB == 0) {
        Rd = 0xFFFFFFFF;
    }
    // 处理非零输入
    if (.itype == .S32) {
        SrcB = ~SrcB;
    }
    Rd = 0xFFFFFFFF;
    for (i = 31; i >= 0; i--) {
        if (SrcB & (1 << i)) {
            Rd = i;
            break;
        }
    }
    // 计算左移位数
    if (.sh == .SH) {
        Rd = 31 - Rd;
    }
```

  __Examples
```asm
FLO        R0, R1;
FLO.U32.SH R1, RZ; // R1 = 0xFFFFFFFF
```

__DefOpcode FLO_R : [FLO]
  __Encoding
    field<8,  4> SType stype==R;
    field<32, 8> Reg rb;
    field<97, 1> SignModi rb.bitnot=False;
  __OperandInfo
    InList<pg, rb>;
    OutList<rd>;
    Order<pg, rd, rb>;
    Bitwidth<rd> = 32;
    Bitwidth<rb> = 32;

__DefOpcode FLO_I : [FLO]
  __Encoding
    field<8,  4> SType stype==I;
    field<32,32> SImm32 vb;
  __OperandInfo
    InList<pg, vb>;
    OutList<rd>;
    Order<pg, rd, vb>;
    Bitwidth<rd> = 32;
    Bitwidth<vb> = 32;

__DefOpcode FLO_U : [FLO]
  __Encoding
    field<8,  4> SType stype==U;
    field<32, 6> UReg urb;
    field<97, 1> SignModi urb.bitnot=False;
  __OperandInfo
    InList<pg, urb>;
    OutList<rd>;
    Order<pg, rd, urb>;
    Bitwidth<rd> = 32;
    Bitwidth<urb> = 32;

__DefOpcode FLO_C : [FLO]
  __Encoding
    field<8,  4> SType stype==C;
    field<32, 22> CMem vb;
    field<97, 1> SignModi vb.bitnot=False;
  __OperandInfo
    InList<pg, vb>;
    OutList<rd>;
    Order<pg, rd, vb>;
    Bitwidth<rd> = 32;
    Bitwidth<vb> = 32;

__DefOptype BREV : [XU]
  __Encoding
    field<0,  8> Optype optype==BREV;
    field<16, 8> Reg rd;

  __Syntax
```asm          
BREV Rd, SrcB      $sched $req ;
```

  __Description
将32bit源操作数SrcB按位取反后输出给Rd，即Rd = ~SrcB。

  __OperandInfo
32bit操作数Rd必须来源于GPR。

32bit操作数SrcB的合法来源包括：GPR、UR、Imm32和cmem。

  __Semantics
```asm
BREV Rd, SrcB:
    Rd = ~SrcB;
```

  __Examples
```asm
BREV R0, R1; // R0 = ~R1
```

__DefOpcode BREV_R : [BREV]
  __Encoding
    field<8,  4> SType stype==R;
    field<32, 8> Reg rb;
  __OperandInfo
    InList<pg, rb>;
    OutList<rd>;
    Order<pg, rd, rb>;
    Bitwidth<rd> = 32;
    Bitwidth<rb> = 32;

__DefOpcode BREV_I : [BREV]
  __Encoding
    field<8,  4> SType stype==I;
    field<32,32> SImm32 vb;
  __OperandInfo
    InList<pg, vb>;
    OutList<rd>;
    Order<pg, rd, vb>;
    Bitwidth<rd> = 32;
    Bitwidth<vb> = 32;

__DefOpcode BREV_U : [BREV]
  __Encoding
    field<8,  4> SType stype==U;
    field<32, 6> UReg urb;
  __OperandInfo
    InList<pg, urb>;
    OutList<rd>;
    Order<pg, rd, urb>;
    Bitwidth<rd> = 32;
    Bitwidth<urb> = 32;

__DefOpcode BREV_C : [BREV]
  __Encoding
    field<8,  4> SType stype==C;
    field<32, 22> CMem vb;
  __OperandInfo
    InList<pg, vb>;
    OutList<rd>;
    Order<pg, rd, vb>;
    Bitwidth<rd> = 32;
    Bitwidth<vb> = 32;

__DefOptype BMSK : [XU]
  __Encoding
    field<0,  8>  Optype optype==BMSK;
    field<16, 8> Reg rd;
    field<24, 8> Reg ra;
    field<81, 1> CWMode cwmode=C;

  __Syntax
```asm          
BMSK{.cwmode} Rd, Ra, SrcB      $sched $req ;

.cwmode = {.CLAMP*, .WRAP}
```

  __Description
从Ra指定的比特位开始，向高位延申的SrcB位填充为1，其他部分填充为0，从而获得一个32bit位宽的掩码，写入Rd。具体语义请参考Semantics部分。

  __OperandInfo
所有输入输出操作数都视为32bit无符号整数。

Rd和Ra必须来源于GPR。

SrcB的合法来源包括：GPR、UR、UImm32和cmem。

  __ModifierInfo
.cwmode可取.CLAMP（默认值）或.WRAP，用于控制掩码的bit范围[hi:lo]：

| .cwmode  | [hi:lo]的计算方式 |
| :---|:---|
| .CLAMP | [hi:lo] = [Ra+SrcB:Ra] |
| .WRAP  | a1=mod(Ra,32)，b1=mod(SrcB,32), [hi:lo] = [a1+b1:a1] |

得到[hi:lo]后，与[31:0]进行比较，二者的交集置为1，其余置为0，并将最终结果的低32bit写入Rd。

  __Semantics
```asm
BMSK.cwmode Rd, Ra, SrcB:
    // 启用.WRAP时计算掩码范围
    a1 = Ra & 0x1f;
    mask0 = (~0) << a1;
    b1 = Rb & 0x1f;
    sum = a1 + b1;
    mask1 = (~0) << sum;

    sumOverflow = sum >= 32 ? true : false;
    bitPositionOverflow = false;
    bitWidthOverflow = false;

    // 启用.CLAMP，计算掩码范围
    if (.cwmode == .CLAMP) {
        if (Ra >= 32) {
            bitPositionOverflow = true;
            mask0 = 0;
        }
        if (Rb >= 32) {
            bitWidthOverflow = true;
        }
    }

    if (sumOverflow || bitPositionOverflow || bitWidthOverflow) {
        mask1 = 0;
    } else if (b1 == 0) {
        mask1 = ~0;
    }
    // 输出32bit掩码
    Rd = mask0 & ~mask1;
```

  __Examples
```asm
BMSK R7, R7, R0 ;
```

__DefOpcode BMSK_RR : [BMSK]
  __Encoding
    field<8,  4> SType stype==RR;
    field<32, 8> Reg rb;
  __OperandInfo
    InList<pg, ra, rb>;
    OutList<rd>;
    Order<pg, rd, ra, rb>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;

__DefOpcode BMSK_RI : [BMSK]
  __Encoding
    field<8,  4> SType stype==RI;
    field<32,32> SImm32 vb;
  __OperandInfo
    InList<pg, ra, vb>;
    OutList<rd>;
    Order<pg, rd, ra, vb>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;

__DefOpcode BMSK_RU : [BMSK]
  __Encoding
    field<8,  4> SType stype==RU;
    field<32, 6> UReg urb;
  __OperandInfo
    InList<pg, ra, urb>;
    OutList<rd>;
    Order<pg, rd, ra, urb>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<urb> = 32;

__DefOpcode BMSK_RC : [BMSK]
  __Encoding
    field<8,  4> SType stype==RC;
    field<32, 22> CMem vb;
  __OperandInfo
    InList<pg, ra, vb>;
    OutList<rd>;
    Order<pg, rd, ra, vb>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;

__DefOptype SGXT : [XU]
  __Encoding
    field<0,  8>  Optype optype==SGXT;
    field<16, 8> Reg rd;
    field<24, 8> Reg ra;
    field<80, 1> IType itype=S32;
    field<81, 1> CWMode cwmode=C;

  __Syntax
```asm          
SGXT{.cwmode}{.itype} Rd, Ra, SrcB      $sched $req ;

.itype = {.S32*, .U32}
.cwmode = {.CLAMP*, .WRAP}
```

  __Description
根据SrcB，将Ra视为SrcB位的整数，并进行零扩展或符号扩展到32bit位宽，写入Rd。

如果SrcB = 0，则输出恒为0。

  __OperandInfo
Ra和Rd必须来源于GPR。

无符号32bit整数SrcB可以来源于GPR、UR、UImm32或cmem。

  __ModifierInfo
.itype可以取.S32（默认值，可省略）或.U32，表示对Ra进行符号扩展还是零扩展。

.cwmode可以取.CLAMP（默认值，可省略）或.WRAP，表示SrcB指定的位宽大于32时的行为：
- .cwmode = .CLAMP：若SrcB > 32，则将Ra视为32位的整数
- .cwmode = .WRAP ：若SrcB > 32，则将Ra视为mod(SrcB, 32)位的整数

因此，.CLAMP模式下的Ra实际有效位宽可以是0~32，而.WRAP模式下的Ra实际有效位宽只能是0~31。

  __Semantics
```asm
SGXT.cwmode.itype Rd, Ra, SrcB:
    // 根据.cwmode和SrcB的值，确定Ra的实际有效位宽
    bitwidth = UINT32(SrcB);
    if (.cwmode == .CLAMP) {
        bitwidth = bitwidth > 32 ? 32 : bitwidth;
    } else {
        bitwidth = mod(bitwidth, 32);
    }
    // 处理0位宽的情况
    if (bitwidth == 0) {
        Rd = 0x00000000;
    // 符号扩展或零扩展到32bit
    } else if (.itype == .U32) {
        Rd = 0x00000000 | Ra[bitwidth-1:0];
    } else {
        // 拷贝bitwidth位至Rd
        Rd = Ra & ((1 << bitwidth) - 1);
        // 检测符号位
        if ((Rd >> (bitwidth - 1)) & 0x1 == 1) {
            // 符号扩展
            Rd = Rd | (~((1 << bitwidth) - 1));
        }
    }
```

  __Examples
```asm
SGXT     R0, R1, 0x3 ;   // 3bit符号扩展到32bit
SGXT.U32 R2, R3, 0x10;   // 16bit零扩展到32bit
```

__DefOpcode SGXT_RR : [SGXT]
  __Encoding
    field<8,  4> SType stype==RR;
    field<32, 8> Reg rb;
  __OperandInfo
    InList<pg, ra, rb>;
    OutList<rd>;
    Order<pg, rd, ra, rb>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;

__DefOpcode SGXT_RI : [SGXT]
  __Encoding
    field<8,  4> SType stype==RI;
    field<32,32> SImm32 vb;
  __OperandInfo
    InList<pg, ra, vb>;
    OutList<rd>;
    Order<pg, rd, ra, vb>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;

__DefOpcode SGXT_RU : [SGXT]
  __Encoding
    field<8,  4> SType stype==RU;
    field<32, 6> UReg urb;
  __OperandInfo
    InList<pg, ra, urb>;
    OutList<rd>;
    Order<pg, rd, ra, urb>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<urb> = 32;

__DefOpcode SGXT_RC : [SGXT]
  __Encoding
    field<8,  4> SType stype==RC;
    field<32, 22> CMem vb;
  __OperandInfo
    InList<pg, ra, vb>;
    OutList<rd>;
    Order<pg, rd, ra, vb>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;
